package cn.com.fone.modules.api.common.split.strategy.impl;

import cn.com.fone.modules.api.common.split.strategy.Strategy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 根据时间进行分表
 */
@Component
public class DateStrategy implements Strategy {

    private Log LOG = LogFactory.getLog(DateStrategy.class);


    /**
     * 根据日期分表
     *
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public String splitTable(Map<String, Object> params) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat(params.get(Strategy.STRATEGY).toString());
        String tebleName = params.get(Strategy.TABLE_NAME).toString().concat("_");
        // 判断参数中是否存在创建时间，有则使用该时间进行查询
        if (!params.isEmpty()
                && params.containsKey(Strategy.EXECUTE_PARAM_VALUES)
                && params.get(Strategy.EXECUTE_PARAM_VALUES) != null) {
            // 当有参数时进行过滤
            if (params.get(Strategy.EXECUTE_PARAM_VALUES) instanceof Map) {

                Map<String, Object> paramMap = (Map<String, Object>) params.get(Strategy.EXECUTE_PARAM_VALUES);
                Map<String, Object> toMapParam = objectToMap(paramMap.get("param1"));
                if (toMapParam.containsKey(params.get(Strategy.SPLIT_FIELD))
                        && toMapParam.get(params.get(Strategy.SPLIT_FIELD)) != null) {
                    LOG.info("获取查询参数为：" + toMapParam.toString());
                    tebleName += sdf.format(toMapParam.get(params.get(Strategy.SPLIT_FIELD)));
                    return tebleName;
                }
            }
        }
        String currDate = sdf.format(new Date());
        LOG.info("使用当前日期作为分表日期:" + currDate);
        // 没有则使用当前时间进行查询
        tebleName += (currDate);
        return tebleName;
    }

    /**
     * 将对象转换为map
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static Map<String, Object> objectToMap(Object obj) throws Exception {
        if (obj == null)
            return null;
        Map<String, Object> map = new HashMap<String, Object>();
        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor property : propertyDescriptors) {
            String key = property.getName();
            if (key.compareToIgnoreCase("class") == 0) {
                continue;
            }
            Method getter = property.getReadMethod();
            Object value = getter != null ? getter.invoke(obj) : null;
            map.put(key, value);
        }
        return map;
    }
}
